import pandas as pd

pd.set_option('display.unicode.east_asian_width', True)
df = pd.read_excel('1—3月入职员工信息.xlsx', index_col=0,
                   sheet_name=['1月', '2月', '3月', '1月员工补充信息', ])
print('原始数据: \n', df)
df1_1, df1_2 = df['1月'], df['1月员工补充信息']
df2, df3 = df['2月'], df['3月']
df1 = pd.merge(df1_1, df1_2)
df_total = pd.concat([df1, df2, df3], ignore_index=True)
print('1—3月入职员工信息: \n', df_total)
print()
groups = df_total.groupby('学历')  # 按学历分组
for group in groups:
    print(group)
print(groups.agg('mean', numeric_only=True)['基本工资'])  # 求均值聚合
# print(groups['基本工资'].agg('mean'))  # 先筛选列再聚合

# 按 “学历” 对员工数据进行分组后，循环打印出每一组的完整信息，包括分组的 “学历标签” 和该学历对应的所有员工数据。
# 代码逻辑拆解
# 1. groups = df_total.groupby('学历')
# 对df_total（1-3 月入职员工的完整数据）按 “学历” 列进行分组，得到分组对象groups。
# 分组规则：将 “学历” 列中值相同的行归为一组，比如 “本科” 为一组，“硕士” 为一组（根据你之前的数据，学历只有这两类）。
# 此时groups本身不直接存储数据，而是存储分组的规则和索引，需要通过循环或聚合操作才能获取具体分组内容。
# 2. for group in groups: print(group)
# 循环遍历分组对象groups，每次循环会取出一个 “分组元组”group。
# 每个group包含两个部分：
# 第一部分：分组的 “标签值”，即 “学历” 列的唯一值（如'本科'或'硕士'）。
# 第二部分：该标签对应的所有员工数据，是一个小型的 DataFrame，包含该学历下所有员工的 “姓名”“职务”“基本工资” 等完整信息。
# print(group)会将这两部分内容一起打印出来，清晰展示每组的构成。'''

# 关键修改说明
# 将原来的 groups.agg('mean')['基本工资'] 改为 groups['基本工资'].agg('mean')：
# 先通过 groups['基本工资'] 筛选出分组后的 “基本工资” 列（仅数值类型）
# 再对筛选后的数值列调用 agg('mean') 计算均值，避免对字符串列的无效计算
# 这样就能正确输出不同学历员工的基本工资均值了。
#
# 区别在于对 “非数值列的处理方式” 和 “计算效率”，具体差异如下：
# 1. groups.agg('mean', numeric_only=True)['基本工资']
# 逻辑：先对分组后的所有列尝试计算均值，但通过 numeric_only=True 参数自动忽略非数值列（只保留数值类型列进行计算），
# 最后通过 ['基本工资'] 提取 “基本工资” 列的结果。
# 特点：
# 会对所有数值列（如 “基本工资”“年龄” 等，若存在）都计算均值，最后只取 “基本工资” 的结果。
# 由于会处理所有数值列，当数据中数值列较多时，计算效率略低（但差异通常不明显）。
# 2. groups['基本工资'].agg('mean')
# 逻辑：先通过 groups['基本工资'] 从分组对象中精准筛选出 “基本工资” 这一列（仅保留这一列数据），再对该列单独计算均值。
# 特点：
# 仅针对 “基本工资” 列进行计算，完全不涉及其他列，计算效率更高（尤其是数据量大时）。
# 逻辑更清晰，直接明确要计算的列，避免对其他列的无效处理。
# 总结建议
# 若只需计算某一列的均值（如 “基本工资”），优先用 groups['基本工资'].agg('mean')，更高效且意图明确。
# 若需要同时计算多个数值列的均值（如 “基本工资”“奖金” 等），可用 groups.agg('mean', numeric_only=True)，再按需提取列结果。
# 两种写法在结果上是一致的，但第二种更推荐（精准、高效）。
